import { RW, waitValue } from 'dlsjs';
import { computed } from 'vue';
import { clone } from 'ramda';
import dayjs from "dayjs"

/**
 * 直接获取dataScope的数据
 * @param value
 * @param params
 * @param $2
 * @return {*}
 */
export function pickRW4Scope(value, params, $2) {
  return RW(params.dataScope)['#/' + $2]
}

/**
 * 根据字符串生成返回值字符语法的单行function
 * @param funcStr
 * @param params
 * @return {function(...[*]): *}
 */
export function createEval(funcStr, params) {
  let func = new Function('dataScope', 'slotScope', 'refScope', 'RW', 'dayjs', 'args', 'return ' + funcStr)
  let slotScope = clone(params.slotScope)
  return (...args) => {
    return func(params.dataScope, slotScope, params.refScope, RW, dayjs, args)
  }
}

/**
 * 创建多步function
 * @param steps
 * @param params
 * @return {(function(...[*]): Promise<void>)|*}
 */
export function createStep(steps, params) {
  return async (...args) => {
    for(let step of steps) {
      if(step.type === 'custom') {
        let func = window.$novue_config?.funcScope?.[step.funcName]
        let paramList = []
        if(step.params) {
          for(let p of step.params) {
            paramList.push(createEval(p, params)(...args))
          }
        }
        if(typeof func === 'function') {
          func(...paramList)
        }
      }
      if(step.type === 'eval') {
        let res = createEval(step.value, params)(...args)
        if(res === false) return
      }
      if(step.type === 'layerFunc') {
        await waitValue(() => params.refScope[step.layerId])
        let func = params.refScope[step.layerId][step.funcName]
        let paramList = []
        if(step.params) {
          for(let p of step.params) {
            paramList.push(createEval(p, params)(...args))
          }
        }
        if(typeof func === 'function') {
          func(...paramList)
        }
      }
    }
  }
}

/**
 * 创建vue的computed对象
 * @param funcStr
 * @param params
 */
export function createComputed(funcStr, params) {
  let func;
  let slotScope = clone(params.slotScope)
  try {
    func = new Function('dataScope', 'slotScope', 'refScope', 'RW', 'args', 'return ' + funcStr)
  }catch (e) {
    console.error(`Custom Code Error From Property: ${params.key}\nErrorCode is: ${funcStr}\nCannot create Function\n${e}`)
    return computed(() => null)
  }
  return computed(() => {
    try {
      return func(params.dataScope, slotScope, params.refScope, RW)
    }catch (e) {
      console.error(`Custom Code Error From Property: ${params.key}\nErrorCode is: ${funcStr}\n${e}`)
      return null
    }
  })
}
